import socket as sk
import threading as mp
#https://www.cnblogs.com/hardfood/p/14263412.html
def c_s_c(sock_in, addr,sock_list:dict): #线程处理函数
    print(sock_list)
    for sock_c in list(sock_list.keys()):#遍历字典
        try:
            sock_list[sock_c].send(("user"+str(addr)+"---in---\n").encode())#遍历通知所有在聊天室的用户有新用户进入
        except:
            pass
    while True:
            readdata = sock_in.recv(1024)#recv函数有阻塞作用，若连接断开或者sock被关闭，返回空
            if readdata:           
                print(readdata) #服务端看信息调试用
                for sock_c in list(sock_list.keys()):   
                    try:
                        sock_list[sock_c].send(str(addr).encode()+readdata)#转发给所用用户
                    except:
                        del sock_list[sock_c] #异常则删除此对象
                        print("del：{} success".format(sock_c))
            else:
                for sock_c in list(sock_list.keys()):
                    try:
                        sock_list[sock_c].send(("user"+str(addr)+"---out---\n").encode())#encode编码为字节序
                    except:
                        pass
                break#退出线程
      
def main():
    s = sk.socket(sk.AF_INET ,sk.SOCK_STREAM)
    s.bind(('',2333))
    s.listen()
    sock_list={}#字典--------------------------------
    while True:
        sock,addr = s.accept()
        sock_list[addr]=sock#将地址作为索引--------------------------------
        t1 = mp.Thread(target=c_s_c, args=(sock, addr,sock_list)) #多进程------
        t1.start()
 
if __name__ == '__main__':
    main()